﻿

using Dapper;

using HBase; 
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace hCommand
{
    class DoubleStock<CS> where CS : AbsCoreStock {
        public int scr;
        public CS deep;
        public CS shallow;
    }

        public abstract class AbsPkEngine<CS> : AbsTaskEngine where CS : AbsCoreStock {
        int index = 1;
        protected List<long> stockIdList = new List<long>();

        protected List<CS> stockList = new List<CS>();
        protected void addStock(CS cs) {
            long csId = cs.id;
            if (!stockIdList.Contains(csId)) {
                stockIdList.Add(csId);
                stockList.Add(cs);
            }

        }
        protected virtual TransRes perTask(IDbConnection conn, IDbTransaction tran) {
            return new TransRes();

        }

        protected virtual void afterTask(IDbConnection conn, IDbTransaction tran, TransRes res) {
        }
        protected sealed override TransRes Execute(IDbConnection conn, IDbTransaction tran) {

            TransRes res = perTask(conn, tran);
            if (res==null)
            {
                return new TransRes("perTask return null");
            }
            if (!res.s) {
                return res;
            }

            List<DoubleStock<CS>> dsList = new List<DoubleStock<CS>>();
            List<long> deepScrList = new List<long>();
            foreach (CS cs in stockList) {
                var loc = conn.Get<CoreWhLoc>(cs.locId, tran);
                if (loc==null) {
                    return new TransRes(cs.boxCode + "get loc null");
                }
                if (loc.deepIndex == 2) {
                    if (!deepScrList.Contains(loc.scr)) {
                        deepScrList.Add(loc.scr);
                    }
                   
                }
           
                addDeep(dsList, loc, cs, loc.deepIndex == 1);
            }
    
            foreach (DoubleStock<CS> ds in dsList) {
                TaskResDto dto = null;
                if (ds.shallow != null) {
                    dto= create(ds.shallow, conn, tran, "",""+ index++);
                }
                if (ds.deep != null) {
                    long relyId = 0;
                    if (dto == null) {
                        relyId = getRelayId(conn, tran, ds.deep, deepScrList); 
                    } else {
                        relyId = dto.paramId;
                    } 
                    create(ds.deep, conn, tran, relyId +"","" + index++);
                } 
            }

            
            afterTask(conn, tran, res);
            stockIdList.Clear();
            stockList.Clear();
            index = 1;
            return res;
        }
        public override String getContent(IDbConnection conn, IDbTransaction trans, AbsCoreStock cs, long desId) {
            return ";"+ index++;
        }
        void addDeep(List<DoubleStock<CS>> dsList, CoreWhLoc loc,CS cs,bool shallow) {
            foreach (DoubleStock<CS> ds in dsList) {
                if (loc.scr == ds.scr) {
                    if (shallow) {
                        if (ds.shallow != null) {
                            throw new Exception("浅货位异常");
                        }
                            ds.shallow = cs;
                    } else {
                        if (ds.deep != null) {
                            throw new Exception("深货位异常");
                        }
                        ds.deep = cs;
                    }
                    return;
                }
               
            }
            DoubleStock<CS> ds1 = new DoubleStock<CS>();
            ds1.scr = loc.scr; 
            if (shallow) {
                ds1.shallow = cs;
            } else {
                ds1.deep = cs;
            }
            dsList.Add(ds1);
        }



        TaskResDto create(CS cs, IDbConnection conn, IDbTransaction tran, String relyId,String pc) {
            long goodDiff = cs.deepDiff;
            int des = getDes(cs);
           return createPkTask(goodDiff,  conn, tran, cs, des, "", getInfo(cs), relyId, pc);
        }


        virtual public String  getInfo(CS cs) {
            return "盘库任务";
        }
        protected abstract int getDes(CS cs);




    }
}
